#pragma once

#include <iostream>
#include <functional>
#include <fstream>
#include <memory>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>

#include "localinetaddr.hpp"
#include "locallog.hpp"

enum ExitCord
{
    SUCCESS = 0,
    ERR_SER,
    ERR_CLI,
    ERR_SOCKET,
    ERR_BIND,
    ERR_LISTEN,
    ERR_CONNECT,
    ERR_FORK,
    ERR_OPEN
};

void SerErr()
{
    Local_Log::LOG(Local_Log::LogLever::LFATAL) << "main error";
    std::cout << "Usage ./server port" << std::endl;
}
void CliErr()
{
    Local_Log::LOG(Local_Log::LogLever::LFATAL) << "main error";
    std::cout << "Usage ./client ip port" << std::endl;
}
class NoCopy
{
public:
    NoCopy() {}
    ~NoCopy() {}
    NoCopy(const NoCopy &cpy) = delete;
    const NoCopy &operator=(const NoCopy &cpy) = delete;
};

/// @brief 获取文件大小
/// @param filename 文件路径加名称
/// @return 文件大小
static int FileSize(const std::string &filename)
{
    std::ifstream lo_inf(filename,std::ios::binary);
    if (!lo_inf.is_open())
        return -1;
    lo_inf.seekg(0, lo_inf.end);
    int filesize = lo_inf.tellg();
    lo_inf.seekg(0, lo_inf.beg);
    lo_inf.close();
    return filesize;
}

/// @brief 读取全部文件
/// @param filename 文件路径加名称
/// @param out 输出结果
/// @return OK/NG
static bool ReadFileContent(const std::string &filename, std::string *out)
{
    // 文本读取，无法处理二进制文件
    // std::ifstream lo_inf(filename);
    // if (!lo_inf.is_open())
    // {
    //     Local_Log::LOG(Local_Log::LogLever::LFATAL) << "ReadFileContent error";
    //     return false;
    // }
    // Local_Log::LOG(Local_Log::LogLever::LFATAL) << "ReadFileContent success";
    // std::string lo_line;
    // while (std::getline(lo_inf, lo_line))
    // {
    //     *out += lo_line;
    // }
    // lo_inf.close();
    // return true;

    // 临时使用，会破坏封装
    int filesize = FileSize(filename);
    if (filesize > 0)
    {
        std::ifstream lo_inf(filename);
        if (!lo_inf.is_open())
            return false;
        out->resize(filesize);
        lo_inf.read((char *)(out->c_str()), filesize);
        lo_inf.close();
        return true;
    }
    else
    {
        return false;
    }
}
